#include "serial_widget.h"

SerialWidget::SerialWidget(QWidget *parent) : QWidget(parent) {
    initUI();
    loadStyleSheet();
    initModel();
    getSerialPortList();

    serialPort = new QSerialPort(this);
    readCount = 0;
    writeConunt = 0;
    sendRecord = "";
    timer = new QTimer(this);

    refreshTime = new QTimer(this);
    refreshTime->start(1000);

    loopSendTimer = new QTimer(this);

    initBindingSignalSlot();
}

void SerialWidget::initUI() {
    // 主布局
    mainLayout = new QGridLayout(this);
    // 设置行比例
    mainLayout->setRowStretch(0, 13);
    mainLayout->setRowStretch(1, 6);
    mainLayout->setRowStretch(2, 1);
    // 列比例
    mainLayout->setColumnStretch(0, 4);
    mainLayout->setColumnStretch(1, 3);
    mainLayout->setColumnStretch(2, 3);

    // 数据接收区域
    receiveGroupBox = new QGroupBox(tr("接收"));
    QVBoxLayout *receiveLayout = new QVBoxLayout();
    receiveTextEdit = new QTextEdit();
    receiveLayout->addWidget(receiveTextEdit);
    receiveGroupBox->setLayout(receiveLayout);
    mainLayout->addWidget(receiveGroupBox, 0, 0);

    // 历史记录区域
    historyGroupBox = new QGroupBox(tr("历史记录"));
    QVBoxLayout *historyLayout = new QVBoxLayout();
    historyTextEdit = new QTextEdit();
    historyLayout->addWidget(historyTextEdit);
    historyGroupBox->setLayout(historyLayout);
    mainLayout->addWidget(historyGroupBox, 0, 1);

    // 多文本区域
    multiGroupBox = new QGroupBox(tr("多文本"));
    QVBoxLayout *multiLayout = new QVBoxLayout();
    multiGroupBox->setLayout(multiLayout);
    mainLayout->addWidget(multiGroupBox, 0, 2);
    QGridLayout *inputGridLayout = new QGridLayout();
    for (int i = 0; i < 13; i++) {
        inputGridLayout->setRowStretch(i, 1);
    }
    multiLayout->addLayout(inputGridLayout);
    QLabel *hexLabel = new QLabel(tr("HEX"));
    QLabel *strLabel = new QLabel(tr("字符串"));
    strLabel->setAlignment(Qt::AlignCenter);
    QLabel *sendLabel = new QLabel(tr("发送"));
    inputGridLayout->addWidget(hexLabel, 0, 0);
    inputGridLayout->addWidget(strLabel, 0, 1);
    inputGridLayout->addWidget(sendLabel, 0, 2);
    for (int i = 0; i < 13; i++) {
        hexCheckBox[i] = new QCheckBox();
        strLineEdit[i] = new QLineEdit();
        sendButton[i] = new QPushButton(QString::number(i + 1));
        inputGridLayout->addWidget(hexCheckBox[i], i + 1, 0);
        inputGridLayout->addWidget(strLineEdit[i], i + 1, 1);
        inputGridLayout->addWidget(sendButton[i], i + 1, 2);
    }
    // 多文本底部两行操作区域
    QHBoxLayout *repeatLayout = new QHBoxLayout();
    repeatCheckBox = new QCheckBox(tr("循环发送"));
    repeatCheckBox->setEnabled(false);
    repeatSpinBox = new QSpinBox(multiGroupBox);
    repeatSpinBox->setMaximum(std::numeric_limits<int>::max()); // 设置最大值为 int 的最大值
    repeatSpinBox->setValue(1000);
    QLabel *repeatLabel = new QLabel(tr("ms"));
    repeatLayout->addWidget(repeatCheckBox);
    repeatLayout->addWidget(repeatSpinBox);
    repeatLayout->addWidget(repeatLabel);
    multiLayout->addLayout(repeatLayout);

    QHBoxLayout *operLayout = new QHBoxLayout();
    saveButton = new QPushButton(tr("保存"));
    loadButton = new QPushButton(tr("加载"));
    restButton = new QPushButton(tr("重置"));
    operLayout->addWidget(saveButton);
    operLayout->addWidget(loadButton);
    operLayout->addWidget(restButton);
    multiLayout->addLayout(operLayout);
    multiLayout->addStretch();

    // mainLayout 第二行
    QHBoxLayout *row2Layout = new QHBoxLayout();
    QVBoxLayout *colOne = new QVBoxLayout();
    QVBoxLayout *colTwo = new QVBoxLayout();
    row2Layout->addLayout(colOne);
    row2Layout->addLayout(colTwo);
    row2Layout->setStretch(0, 1);
    row2Layout->setStretch(1, 9);
    mainLayout->addLayout(row2Layout, 1, 0, 1, 3);

    QGridLayout *selectGridLayout = new QGridLayout();
    selectGridLayout->setColumnStretch(0, 2);
    selectGridLayout->setColumnStretch(1, 3);
    colOne->addLayout(selectGridLayout);
    QLabel *serialLabel = new QLabel(tr("串口"));
    serialComboBox = new ClickComboBox();
    QLabel *baudRateLabel = new QLabel(tr("波特率"));
    baudRateComboBox = new QComboBox(this);
    QLabel *dataBitsLabel = new QLabel(tr("数据位"));
    dataBitsComboBox = new QComboBox(this);
    QLabel *parityLabel = new QLabel(tr("校验位"));
    parityComboBox = new QComboBox(this);
    QLabel *stopBitsLabel = new QLabel(tr("停止位"));
    stopBitsComboBox = new QComboBox(this);
    QLabel *flowControlLabel = new QLabel(tr("流控"));
    flowControlComboBox = new QComboBox(this);
    selectGridLayout->addWidget(serialLabel, 0, 0);
    selectGridLayout->addWidget(serialComboBox, 0, 1);
    selectGridLayout->addWidget(baudRateLabel, 1, 0);
    selectGridLayout->addWidget(baudRateComboBox, 1, 1);
    selectGridLayout->addWidget(dataBitsLabel, 2, 0);
    selectGridLayout->addWidget(dataBitsComboBox, 2, 1);
    selectGridLayout->addWidget(parityLabel, 3, 0);
    selectGridLayout->addWidget(parityComboBox, 3, 1);
    selectGridLayout->addWidget(stopBitsLabel, 4, 0);
    selectGridLayout->addWidget(stopBitsComboBox, 4, 1);
    selectGridLayout->addWidget(flowControlLabel, 5, 0);
    selectGridLayout->addWidget(flowControlComboBox, 5, 1);

    QGridLayout *operateGridLayout = new QGridLayout();
    colTwo->addLayout(operateGridLayout);
    onToOffButton = new QPushButton(tr("打开串口"));
    onToOffButton->setObjectName("onToOffButton");
    operateGridLayout->addWidget(onToOffButton, 0, 0, 2, 1);
    clearReciveButton = new QPushButton(tr("清空接收"));
    operateGridLayout->addWidget(clearReciveButton, 0, 1);
    reciveTimeCheckBox = new QCheckBox(tr("显示接收时间"));
    operateGridLayout->addWidget(reciveTimeCheckBox, 0, 2);
    hexShowCheckBox = new QCheckBox(tr("HEX显示"));
    operateGridLayout->addWidget(hexShowCheckBox, 0, 3);
    runModeButton = new QPushButton(tr("运行模式"));
    // operateGridLayout->addWidget(runModeButton, 0, 4);
    hideControlPanelButton = new QPushButton(tr("隐藏面板"));
    operateGridLayout->addWidget(hideControlPanelButton, 0, 5);
    saveReciveButton = new QPushButton(tr("保存接收"));
    operateGridLayout->addWidget(saveReciveButton, 1, 1);
    autoLineCheckBox = new QCheckBox(tr("自动换行"));
    operateGridLayout->addWidget(autoLineCheckBox, 1, 3);
    downloadModeButton = new QPushButton(tr("下载模式"));
    // operateGridLayout->addWidget(downloadModeButton, 1, 4);
    hideHistoryButton = new QPushButton(tr("隐藏历史"));
    operateGridLayout->addWidget(hideHistoryButton, 1, 5);

    // 发送消息区域
    QVBoxLayout *sendLayout = new QVBoxLayout();
    colTwo->addLayout(sendLayout);
    QHBoxLayout *sendSelectLayout = new QHBoxLayout();
    sendLayout->addLayout(sendSelectLayout);
    tiemSendCheckBox = new QCheckBox(tr("定时发送"));
    tiemSendCheckBox->setEnabled(false);
    sendSelectLayout->addWidget(tiemSendCheckBox);
    tiemSendLineEdit = new QLineEdit();
    tiemSendLineEdit->setText("1000");
    tiemSendLineEdit->setMaximumWidth(100);
    sendSelectLayout->addWidget(tiemSendLineEdit);
    QLabel *timeSendLabel = new QLabel(tr("ms/次"));
    sendSelectLayout->addWidget(timeSendLabel);
    sendNewRowCheckBox = new QCheckBox(tr("发送新行"));
    sendSelectLayout->addWidget(sendNewRowCheckBox);
    hexSendCheckBox = new QCheckBox(tr("HEX发送"));
    sendSelectLayout->addWidget(hexSendCheckBox);
    // formatInCheckBox = new QCheckBox(tr("格式输入"));
    // sendSelectLayout->addWidget(formatInCheckBox);
    sendSelectLayout->addStretch();

    QHBoxLayout *sendMessageLayout = new QHBoxLayout();
    sendLayout->addLayout(sendMessageLayout);
    sendMessageRowButton = new QPushButton(tr("发送"));
    sendMessageRowButton->setEnabled(false);
    sendMessageLayout->addWidget(sendMessageRowButton);
    sendMessageEdit = new QTextEdit(this);
    sendMessageEdit->setFixedHeight(60);
    sendMessageEdit->setObjectName("sendMessageEdit");
    sendMessageLayout->addWidget(sendMessageEdit);

    // 底部状态显示
    QVBoxLayout *bottomLayout = new QVBoxLayout();
    mainLayout->addLayout(bottomLayout, 2, 0, 1, 3);
    QHBoxLayout *statusLayout = new QHBoxLayout();
    statusLayout->setAlignment(Qt::AlignBottom);
    bottomLayout->addStretch();
    bottomLayout->addLayout(statusLayout);
    statusLabel = new QLabel();
    statusLayout->addWidget(statusLabel);
    receiveLabel = new QLabel();
    statusLayout->addWidget(receiveLabel);
    sendStatusLabel = new QLabel();
    statusLayout->addWidget(sendStatusLabel);
    timeLabel = new QLabel();
    statusLayout->addWidget(timeLabel);
}

void SerialWidget::loadStyleSheet() {
    QFile file(":/resources/style/serial_widget.qss");
    if (file.open(QFile::ReadOnly)) {
        QString styleSheet = this->styleSheet();
        styleSheet += file.readAll();
        this->setStyleSheet(styleSheet);
    }
}

void SerialWidget::initModel() {
    QStringList baudModel = {"4800", "9600", "19200", "38400", "57600", "115200", "230400", "460800", "921600"};
    baudRateComboBox->addItems(baudModel);
    baudRateComboBox->setCurrentIndex(5);

    QStringList dataBitsModel = {"5", "6", "7", "8"};
    dataBitsComboBox->addItems(dataBitsModel);
    // dataBitsComboBox->setCurrentIndex(3);
    dataBitsComboBox->setCurrentText("8");

    QStringList parityModel = {"None", "Even", "Mark", "Odd", "Space"};
    parityComboBox->addItems(parityModel);
    parityComboBox->setCurrentIndex(0);

    QStringList stopBitModel;
    stopBitModel << "One" << "OnePointFive" << "Two";
    stopBitsComboBox->addItems(stopBitModel);
    stopBitsComboBox->setCurrentIndex(0);

    QStringList flowControlModel;
    flowControlModel << "None" << "Hardware" << "Software";
    flowControlComboBox->addItems(flowControlModel);
    flowControlComboBox->setCurrentIndex(0);
}

void SerialWidget::getSerialPortList() {
    serialComboBox->clear();
    QList<QSerialPortInfo> selrialList = QSerialPortInfo::availablePorts();
    for (QSerialPortInfo serialPortInfo : selrialList) {
        serialComboBox->addItem(serialPortInfo.portName());
    }
}

// 连接信号槽
void SerialWidget::initBindingSignalSlot() {
    connect(serialPort, &QSerialPort::readyRead, this, &SerialWidget::onSerialReadToRead);
    connect(onToOffButton, &QPushButton::clicked, this, &SerialWidget::onOpenOrCloseSerialPort);
    connect(sendMessageRowButton, &QPushButton::clicked, this, &SerialWidget::onSendContext);
    connect(tiemSendCheckBox, &QCheckBox::clicked, this, &SerialWidget::on_tiemSendCheckBox_clicked);
    connect(clearReciveButton, &QPushButton::clicked, this, &SerialWidget::on_clearReciveButton_clicked);
    connect(saveReciveButton, &QPushButton::clicked, this, &SerialWidget::on_saveReciveButton_clicked);
    connect(refreshTime, &QTimer::timeout, this, &SerialWidget::on_refreshTime);
    connect(hideControlPanelButton, &QPushButton::clicked, this, &SerialWidget::on_hideControlPanelButton_clicked);
    connect(hideHistoryButton, &QPushButton::clicked, this, &SerialWidget::on_hideHistoryButton_clicked);
    connect(serialComboBox, &ClickComboBox::clicked, this, &SerialWidget::on_serialComboBox_clicked);
    // connect(hexShowCheckBox, &QCheckBox::clicked, this, &SerialWidget::on_hexShowCheckBox_clicked);
    connect(timer, &QTimer::timeout, [=]() { onSendContext(); });
    connect(loopSendTimer, &QTimer::timeout, [=]() { on_loopSendTimer_timeout(); });
    connect(repeatCheckBox, &QCheckBox::clicked, this, &SerialWidget::on_repeatCheckBox_clicked);

    // 多文本发送
    for (int i = 0; i < 13; i++) {
        connect(sendButton[i], &QPushButton::clicked, [this, i]() { on_sendButtonItemClicked(i); });
    }
    connect(restButton, &QPushButton::clicked, this, &SerialWidget::on_restButton_clicked);
    connect(saveButton, &QPushButton::clicked, this, &SerialWidget::on_saveButton_clicked);
    connect(loadButton, &QPushButton::clicked, this, &SerialWidget::on_loadButton_clicked);
}

void SerialWidget::onOpenOrCloseSerialPort() {
    qDebug() << "onOpenOrCloseSerialPort";
    if (serialPort->isOpen()) {
        serialPort->close();
        if (timer->isActive()) {
            timer->stop();
            tiemSendCheckBox->setChecked(false);
        }
        tiemSendCheckBox->setEnabled(false);
        serialComboBox->setEnabled(true);
        baudRateComboBox->setEnabled(true);
        dataBitsComboBox->setEnabled(true);
        parityComboBox->setEnabled(true);
        stopBitsComboBox->setEnabled(true);
        flowControlComboBox->setEnabled(true);
        onToOffButton->setText("打开串口");
        statusLabel->setText("串口已关闭");
        onToOffButton->setStyleSheet("");
        sendMessageRowButton->setEnabled(true);
        repeatCheckBox->setEnabled(true);

    } else {
        // 选择端口
        serialPort->setPortName(serialComboBox->currentText());
        // 配置波特率
        serialPort->setBaudRate(baudRateComboBox->currentText().toInt());
        // 配置数据位
        serialPort->setDataBits(QSerialPort::DataBits(dataBitsComboBox->currentText().toInt()));
        // 配置校验位
        QString parity = parityComboBox->currentText();
        if (parity == "None") {
            serialPort->setParity(QSerialPort::NoParity);
        } else if (parity == "Even") {
            serialPort->setParity(QSerialPort::EvenParity);
        } else if (parity == "Mark") {
            serialPort->setParity(QSerialPort::MarkParity);
        } else if (parity == "Odd") {
            serialPort->setParity(QSerialPort::OddParity);
        } else if (parity == "Space") {
            serialPort->setParity(QSerialPort::SpaceParity);
        } else {
            serialPort->setParity(QSerialPort::UnknownParity);
        }
        // 配置停止位
        QString stopBits = stopBitsComboBox->currentText();
        if (stopBits == "One") {
            serialPort->setStopBits(QSerialPort::OneStop);
        } else if (stopBits == "OnePointFive") {
            serialPort->setStopBits(QSerialPort::OneAndHalfStop);
        } else if (stopBits == "Two") {
            serialPort->setStopBits(QSerialPort::TwoStop);
        } else {
            serialPort->setStopBits(QSerialPort::UnknownStopBits);
        }
        // 流控
        QString flow = flowControlComboBox->currentText();
        if (flow == "None") {
            serialPort->setFlowControl(QSerialPort::NoFlowControl);
        } else if (flow == "Hardware") {
            serialPort->setFlowControl(QSerialPort::HardwareControl);
        } else if (flow == "Software") {
            serialPort->setFlowControl(QSerialPort::SoftwareControl);
        } else {
            serialPort->setFlowControl(QSerialPort::UnknownFlowControl);
        }
        // 打开串口
        if (serialPort->open(QIODevice::ReadWrite)) {
            qDebug() << "串口打开成功";
            statusLabel->setText("串口打开成功");
            // 更新控件状态
            tiemSendCheckBox->setEnabled(true);
            serialComboBox->setEnabled(false);
            baudRateComboBox->setEnabled(false);
            dataBitsComboBox->setEnabled(false);
            parityComboBox->setEnabled(false);
            stopBitsComboBox->setEnabled(false);
            flowControlComboBox->setEnabled(false);
            onToOffButton->setText("关闭串口");
            QString style = "QPushButton {background-color: #dcdfe6;border: "
                            "1px solid gray;border-radius: 5px;height: 30px;}" +
                            onToOffButton->styleSheet();
            onToOffButton->setStyleSheet(style);
            sendMessageRowButton->setEnabled(false);
            repeatCheckBox->setEnabled(false);
        } else {
            qDebug() << "串口打开失败";
            statusLabel->setText("串口打开失败, 检查串口是否被占用");
        }
    }
}

void SerialWidget::onSendContext() {
    qDebug() << "发送数据.....";
    QString text = sendMessageEdit->toPlainText();
    int write_size = 0;
    QByteArray data;
    // 检查是否是16进制数据
    if (hexSendCheckBox->isChecked()) {
        // 处理16进制数据 如 AA BB 0D
        QStringList list = text.split(' ', Qt::SkipEmptyParts);
        foreach (QString hex, list) {
            bool ok;
            char byte = hex.toInt(&ok, 16);
            if (ok && hex.length() == 2) {
                data.append(byte);
            } else {
                statusLabel->setText(tr("发送失败, 请检查数据是否是16进制数据"));
                return;
            }
        }
    } else {
        data = text.toUtf8();
    }
    // 发送新行
    if (sendNewRowCheckBox->isChecked()) {
        data.append("\r\n");
    }
    // 发送数据
    write_size = serialPort->write(data);
    if (write_size == -1) {
        statusLabel->setText(tr("发送失败"));
    } else {
        writeConunt += write_size;
        statusLabel->setText(tr("发送成功"));
        QString sendText = QString("发送:" + QString::number(writeConunt));
        sendStatusLabel->setText(sendText);
        if (text != sendRecord) {
            historyTextEdit->append(text);
            sendRecord = text;
        }
    }
    qDebug() << "sendData: " << data;
}
// 接收数据
void SerialWidget::onSerialReadToRead() {
    QByteArray readData = serialPort->readAll();
    QString receiveTime = "";
    // 接收时间显示
    if (reciveTimeCheckBox->isChecked()) {
        receiveTime += "[" + getDateTimeToFormat() + "]  ";
    }
    if (hexShowCheckBox->isChecked()) {
        // 16 进制格式显示
        QString hexStr;
        for (char byte : readData) {
            hexStr += QString("%1 ").arg((quint8)byte, 2, 16, QLatin1Char('0')).toUpper();
        }
        receiveTextEdit->insertPlainText(receiveTime + hexStr.trimmed());
    } else {
        // 文本形式显示 非可打印字符显示
        receiveTextEdit->insertPlainText(receiveTime + readData);
    }
    if (autoLineCheckBox->isChecked()) {
        receiveTextEdit->append("");
    }
    readCount += readData.size();
    receiveLabel->setText(tr("接收:") + QString::number(readCount));
    receiveTextEdit->moveCursor(QTextCursor::End);
    receiveTextEdit->ensureCursorVisible();
}

void SerialWidget::on_tiemSendCheckBox_clicked(bool checked) {
    if (checked) {
        timer->start(tiemSendLineEdit->text().toInt());
    } else {
        timer->stop();
    }
}

void SerialWidget::on_clearReciveButton_clicked() { receiveTextEdit->clear(); }

void SerialWidget::on_saveReciveButton_clicked() {
    QString desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存接收数据"), desktopDir, tr("*.txt"));
    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            return;
        }
        QTextStream out(&file);
        out << receiveTextEdit->toPlainText();
        file.close();
    }
}

void SerialWidget::on_refreshTime() {
    QString timeStr = getDateTimeToFormat();
    timeLabel->setText(timeStr);
}

void SerialWidget::on_hexShowCheckBox_clicked(bool checked) {
    if (checked) {
        QString str = receiveTextEdit->toPlainText();
        QByteArray byteArray = str.toUtf8();
        byteArray = byteArray.toHex();
        receiveTextEdit->setText(byteArray);
    } else {
        QString str = receiveTextEdit->toPlainText();
        QByteArray byteArray = str.toUtf8();
        byteArray = QByteArray::fromHex(byteArray);
        receiveTextEdit->setText(QString::fromUtf8(byteArray));
    }
}

void SerialWidget::on_hideControlPanelButton_clicked() {
    if (showControlPanel) {
        multiGroupBox->hide();
        mainLayout->setColumnStretch(2, 0); // 将多文本区域的列比例设为 0
        mainLayout->setColumnStretch(0, 7); // 增加数据接收区域的列比例
        showControlPanel = false;
        hideControlPanelButton->setText("显示面板");
    } else {
        multiGroupBox->show();
        mainLayout->setColumnStretch(2, 3); // 恢复多文本区域的列比例
        mainLayout->setColumnStretch(0, 4); // 恢复数据接收区域的列比例
        showControlPanel = true;
        hideControlPanelButton->setText("隐藏面板");
    }
}

void SerialWidget::on_hideHistoryButton_clicked() {
    if (showHistory) {
        historyGroupBox->hide();
        mainLayout->setColumnStretch(1, 0); // 将历史记录区域的列比例设为 0
        mainLayout->setColumnStretch(0, 7); // 增加数据接收区域的列比例
        showHistory = false;
        hideHistoryButton->setText("显示历史");
    } else {
        historyGroupBox->show();
        mainLayout->setColumnStretch(1, 3); // 恢复历史记录区域的列比例
        mainLayout->setColumnStretch(0, 4); // 恢复数据接收区域的列比例
        showHistory = true;
        hideHistoryButton->setText("隐藏历史");
    }
}

void SerialWidget::on_serialComboBox_clicked() { getSerialPortList(); }

void SerialWidget::on_sendButtonItemClicked(int index) {
    // 获取索引文本
    QString text = strLineEdit[index]->text();
    // 设置到 底部发送框
    sendMessageEdit->clear();
    sendMessageEdit->setText(text);
    // 检查hex
    if (hexCheckBox[index]->isChecked()) {
        hexSendCheckBox->setChecked(true);
    }
    // 手动发送
    onSendContext();
}

void SerialWidget::on_loopSendTimer_timeout() {
    if (currentIndex < 13) {
        if (!strLineEdit[currentIndex]->text().isEmpty()) {
            emit sendButton[currentIndex]->clicked();
        }
        currentIndex++;
    } else {
        currentIndex = 0;
    }
}

void SerialWidget::on_repeatCheckBox_clicked(bool checked) {
    if (checked) {
        loopSendTimer->start(repeatSpinBox->text().toInt());
    } else {
        loopSendTimer->stop();
    }
}

void SerialWidget::on_restButton_clicked() {
    for (int i = 0; i < 13; i++) {
        strLineEdit[i]->clear();
        hexCheckBox[i]->setChecked(false);
    }
}

void SerialWidget::on_saveButton_clicked() {
    QString desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存数据"), desktopDir, tr("*.txt"));
    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            return;
        }
        QTextStream out(&file);
        for (int i = 0; i < 13; i++) {
            out << hexCheckBox[i]->isChecked() << "," << strLineEdit[i]->text() << "\n";
        }
        file.close();
    }
}

void SerialWidget::on_loadButton_clicked() {
    int i = 0;
    QString desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString fileName = QFileDialog::getOpenFileName(this, tr("加载数据"), desktopDir, tr("*.txt"));
    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            return;
        }
        QTextStream in(&file);
        while (!in.atEnd() && i < 13) {
            QString line = in.readLine();
            QStringList list = line.split(",");
            if (list.size() == 2) {
                hexCheckBox[i]->setChecked(list[0].toInt());
                strLineEdit[i]->setText(list[1]);
            }
            i++;
        }
    }
}